﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using RainEngine.SceneManagement;
using System.ComponentModel;


namespace RainEngine.SceneNodes
{
    /// <summary>
    /// 所有2D图像节点对象的抽象基类
    /// </summary>
    public class Renderable2DSceneNode :SceneNode 
    {
        #region 成员变量和构造函数       

        /// <summary>
        /// 引擎的引用
        /// </summary>
        protected RainGE engine;
        
        /// <summary>
        /// 节点使用的图像文件名称，包含路径
        /// </summary>
        protected string textureName;       
        
        /// <summary>
        /// 节点使用的图像
        /// </summary>
        protected Texture2D texture;

        /// <summary>
        /// 由场景淡入淡出过程决定的纹理透明颜色
        /// </summary>
        protected Color alphaTextureColor;
        
        /// <summary>
        /// 节点的2D屏幕坐标
        /// </summary>
        protected Vector2 position;
        
        /// <summary>
        /// 节点的大小
        /// </summary>
        protected Vector2 size;

        /// <summary>
        /// 节点是否可见
        /// </summary>
        protected bool visible = true;

        /// <summary>
        /// 纹理的源矩形
        /// </summary>
        Rectangle? rectSourceOrigin = null;

        /// <summary>
        /// 是否从内嵌的资源加载图像
        /// </summary>
        protected bool useResource = false;

        /// <summary>
        /// 创建一个新Renderable2DSceneNode对象
        /// </summary>
        /// <param name="engine"></param>
        /// <param name="setScene"></param>
        /// <param name="setPosition"></param>
        /// <param name="setTextureName"></param>
        public Renderable2DSceneNode(RainGE engine, Scene setScene, string setTextureName)
            : this(engine, setScene, setTextureName, Vector2.Zero , 0, Vector2.Zero, SpriteEffects.None, 0, Color.White, false)
        { }        

        /// <summary>
        /// 创建一个新Renderable2DSceneNode对象
        /// </summary>
        /// <param name="engine"></param>
        /// <param name="setScene"></param>
        /// <param name="setPosition"></param>
        /// <param name="setTextureName"></param>
        public Renderable2DSceneNode(RainGE engine, Scene setScene, Vector2 setPosition, string setTextureName)
            : this(engine, setScene, setTextureName, setPosition ,0,Vector2.Zero ,SpriteEffects.None, 0,Color .White,false)
        { }        

        /// <summary>
        /// 创建一个新Renderable2DSceneNode对象
        /// </summary>
        /// <param name="setEngine">引擎</param>
        /// <param name="setScene">所属场景</param>
        /// <param name="setTextureName">控件使用的纹理名称</param>
        /// <param name="setPosition">控件的2D屏幕位置</param>
        /// <param name="setRotation">旋转</param>
        /// <param name="setOrigin">初始点</param>
        /// <param name="setEffect">SpriteEffect</param>
        /// <param name="setLayerDepth">层深度</param>
        /// <param name="setColor">Sprite的调制颜色</param>     
        internal Renderable2DSceneNode(RainGE setEngine, Scene setScene, string setTextureName, Vector2 setPosition, float setRotation, Vector2 setOrigin, SpriteEffects setEffect, float setLayerDepth, Color setColor,bool useResource)
            : base(setEngine.GraphicsDevice,setScene)
        {
            this.engine = setEngine;
            this.UpdateOrder = SceneNodeOrdering.UINode.GetValue();
            this.position = setPosition;            
            this.Rotation = setRotation;
            this.Origin = setOrigin;            
            this.SpriteEffect = setEffect;
            this.LayerDepth = setLayerDepth;
            this.Color = setColor;
            this.useResource = useResource;
            this.TextureName  = setTextureName;
        }  
        #endregion

        #region 属性
       
        /// <summary>
        /// 获取或设置UI控件使用的图像文件名称，包含路径
        /// </summary>
        public string TextureName
        {
            get { return textureName; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    textureName = value;
                    if(!useResource )
                        texture = engine.Content.Load<Texture2D>(textureName);
                    else
                        texture =RainGE .ResourceContent.Load<Texture2D>(textureName);
                }
            }
        }

        /// <summary>
        /// 获取或设置控件的2D屏幕位置
        /// </summary>
        public Vector2 Position
        {
            get { return position; }
            set
            {
                position = value;
                OnLocationChanged();                
            }
        }

        /// <summary>
        /// 获取或设置控件的大小
        /// </summary>
        public Vector2 Size
        {
            get { return size; }
            set
            {
                size = value;
                OnSizeChanged();
            }
        }

        /// <summary>
        /// 获取或设置Sprite的旋转值
        /// </summary>
        public float Rotation { get;set;}
        
        /// <summary>
        /// 获取或设置Sprite的旋转起始点
        /// </summary>
        public Vector2 Origin  { get;set;}

        /// <summary>
        /// 获取或设置纹理的普通状态的源矩形
        /// </summary>
        public Rectangle? RectSourceOrigin
        {
            get { return (Rectangle)rectSourceOrigin; }
            set { rectSourceOrigin = value; }
        }

        /// <summary>
        /// 获取或设置层深度
        /// </summary>
        public float LayerDepth { get;set;}

        /// <summary>
        /// 获取或设置控制水平翻转还是垂直翻转的SpriteEffect
        /// </summary>
        public SpriteEffects SpriteEffect { get;set;}

        /// <summary>
        /// 获取或设置Sprite的调制颜色
        /// </summary>
        public Color Color { get;set;}

        /// <summary>
        /// 获取或设置是否可见
        /// </summary>
        [Category("基本属性")]
        [Description("该节点是否可见")]
        public virtual bool Visible
        {
            get { return visible; }
            set
            {
                visible = value;
                OnVisibleChanged(EventArgs.Empty);
            }
        }
        
        #endregion

        #region 事件

        /// <summary>
        /// 当Visible属性改变时引发的事件。
        /// </summary>
        public event EventHandler VisibleChanged;

        /// <summary>
        ///  VisibleChanged事件的处理程序。
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnVisibleChanged(EventArgs e)
        {
            if (VisibleChanged != null)
                VisibleChanged(this.visible, e);
        }

        //当控件的Size属性值更改时引发的事件
        public event EventHandler SizeChanged;

        /// <summary>
        /// SizeChanged事件的处理程序
        /// </summary>
        protected  virtual void OnSizeChanged()
        {
            if(SizeChanged !=null)
                SizeChanged(this,EventArgs .Empty ); 
        }

        /// <summary>
        /// 当控件的Position属性值更改时引发的事件
        /// </summary>
        public event EventHandler LocationChanged;

        /// <summary>
        /// LocationChanged事件的处理程序
        /// </summary>
        protected virtual void OnLocationChanged()
        {
            if (LocationChanged != null)
                LocationChanged(this, EventArgs.Empty);
        }

        #endregion

        public override void Initialize()
        {
            if (graphicsDevice.IsDisposed)
                return;
            isInitialized = true;
        }

        public virtual int Draw(GameTime gameTime)
        {
            //获取图像淡入淡出的透明颜色
            alphaTextureColor = new Color(Color.R, Color.G, Color.B, Scene.TransitionAlpha);

            //绘制图像
            RainGE.SpriteBatch.Draw(texture, new Rectangle((int)Position.X, (int)Position.Y, (int)size.X, (int)size.Y), rectSourceOrigin, alphaTextureColor, Rotation, Origin, SpriteEffect, LayerDepth);

            return 1;

        }        
    }
}
